package com.jinhongone.pattern.creater.factory.config_simpleFactory;


import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Properties;
import java.util.Set;

/*
 * 简单工厂模式扩展: 配置文件+简单工厂【开发中常用模式】
 *   作用：使用配置文件让简单工厂和具体产品进行解耦，遵守开闭原则
 * */
public class CoffeeFactory {
    //1.创建容器存放产品对象
    private static HashMap<String, Coffee> container = new HashMap<>();

    //2.初始化时将配置文件中产品对象实例化并存放到容器中方便后续使用
    static {
        //加载properties配置文件
        Properties p = new Properties();
        InputStream is = CoffeeFactory.class.getClassLoader().getResourceAsStream("bean.properties");
        try {
            p.load(is);
            //通过配置文件获取具体产品的全类名，反射创建实例放入容器
            Set<Object> keys = p.keySet();
            for (Object key : keys) {
                String className = p.getProperty((String) key);
                // 普通反射方式创建对象
//                Coffee o = (Coffee) Class.forName(className).newInstance();
                //具体方法使用单例模式且防反射
                Constructor declaredConstructor = Class.forName(className).getDeclaredConstructor();
                declaredConstructor.setAccessible(true);
                Coffee o = (Coffee) declaredConstructor.newInstance();
                container.put((String) key, o);
            }

        } catch (IOException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    //3.静态工厂提供产品，从容器中获取对应产品对象
    public static Coffee getCoffee(String coffeeName) {
        return container.get(coffeeName);
    }
}
